From 10a74ed0a21af7578b62582c4e43c1312eb25fdd Mon Sep 17 00:00:00 2001 From: "kaf24@localhost.localdomain" Date: Mon, 28 Aug 2006 12:59:07 +0100 Subject: [PATCH] [HVM] [SMBIOS] Duplicate UUID into serial number in SMBIOS tables. Windows zeroes out the UUID in the SMBIOS tables, but the identifier is often needed by systems management code. Duplicating the UUID as the virtual system's serial number should help. Signed-off-by: Andrew D. Ball --- tools/firmware/hvmloader/smbios.c | 12 +++++-- tools/firmware/hvmloader/util.c | 54 +++++++++++++++++++++++++++++++ tools/firmware/hvmloader/util.h | 10 ++++++ 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/tools/firmware/hvmloader/smbios.c b/tools/firmware/hvmloader/smbios.c index 64a84500ad..57618b2098 100644 --- a/tools/firmware/hvmloader/smbios.c +++ b/tools/firmware/hvmloader/smbios.c @@ -116,8 +116,10 @@ smbios_table_size(uint32_t vcpus, const char *xen_version, /* type 0: "Xen", xen_version, and release_date */ size += strlen("Xen") + strlen(xen_version) + 2; - /* type 1: "Xen", xen_version, "HVM domU" */ - size += strlen("Xen") + strlen("HVM domU") + strlen(xen_version) + 3; + /* type 1: "Xen", xen_version, "HVM domU", UUID as string for + serial number */ + size += strlen("Xen") + strlen("HVM domU") + strlen(xen_version) + + 36 + 4; /* type 3: "Xen" */ size += strlen("Xen") + 1; /* type 4: socket designation ("CPU n"), processor_manufacturer */ @@ -371,6 +373,7 @@ static void * smbios_type_1_init(void *start, const char *xen_version, uint8_t uuid[16]) { + char uuid_str[37]; struct smbios_type_1 *p = (struct smbios_type_1 *)start; p->header.type = 1; p->header.length = sizeof(struct smbios_type_1); @@ -379,7 +382,7 @@ smbios_type_1_init(void *start, const char *xen_version, p->manufacturer_str = 1; p->product_name_str = 2; p->version_str = 3; - p->serial_number_str = 0; + p->serial_number_str = 4; memcpy(p->uuid, uuid, 16); @@ -395,6 +398,9 @@ smbios_type_1_init(void *start, const char *xen_version, start += strlen("HVM domU") + 1; strcpy((char *)start, xen_version); start += strlen(xen_version) + 1; + uuid_to_string(uuid_str, uuid); + strcpy((char *)start, uuid_str); + start += strlen(uuid_str) + 1; *((uint8_t *)start) = 0; return start+1; diff --git a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c index d23e546859..2ce5367fb9 100644 --- a/tools/firmware/hvmloader/util.c +++ b/tools/firmware/hvmloader/util.c @@ -174,3 +174,57 @@ cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) : "0" (idx) ); } +/* Write a two-character hex representation of 'byte' to digits[]. + Pre-condition: sizeof(digits) >= 2 */ +void +byte_to_hex(char *digits, uint8_t byte) +{ + uint8_t nybbel = byte >> 4; + + if (nybbel > 9) + digits[0] = 'a' + nybbel-10; + else + digits[0] = '0' + nybbel; + + nybbel = byte & 0x0f; + if (nybbel > 9) + digits[1] = 'a' + nybbel-10; + else + digits[1] = '0' + nybbel; +} + +/* Convert an array of 16 unsigned bytes to a DCE/OSF formatted UUID + string. + + Pre-condition: sizeof(dest) >= 37 */ +void +uuid_to_string(char *dest, uint8_t *uuid) +{ + int i = 0; + char *p = dest; + + for (i = 0; i < 4; ++i) { + byte_to_hex(p, uuid[i]); + p += 2; + } + *p++ = '-'; + for (i = 4; i < 6; ++i) { + byte_to_hex(p, uuid[i]); + p += 2; + } + *p++ = '-'; + for (i = 6; i < 8; ++i) { + byte_to_hex(p, uuid[i]); + p += 2; + } + *p++ = '-'; + for (i = 8; i < 10; ++i) { + byte_to_hex(p, uuid[i]); + p += 2; + } + *p++ = '-'; + for (i = 10; i < 16; ++i) { + byte_to_hex(p, uuid[i]); + p += 2; + } +} diff --git a/tools/firmware/hvmloader/util.h b/tools/firmware/hvmloader/util.h index 243c26c979..5d21e8bc7f 100644 --- a/tools/firmware/hvmloader/util.h +++ b/tools/firmware/hvmloader/util.h @@ -25,6 +25,16 @@ void *memcpy(void *dest, const void *src, unsigned n); void *memset(void *s, int c, unsigned n); char *itoa(char *a, unsigned int i); +/* convert a byte to two lowercase hex digits, with no terminating NUL + character. digits[] must have at least two elements. */ +void byte_to_hex(char *digits, uint8_t byte); + +/* Convert an array of 16 unsigned bytes to a DCE/OSF formatted UUID + string. + + Pre-condition: sizeof(dest) >= 37 */ +void uuid_to_string(char *dest, uint8_t *uuid); + /* Debug output */ void puts(const char *s); -- 2.30.2